package com.custom.base.http

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Handler
import com.custom.base.config.BaseConfig

import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream

import okhttp3.Call
import okhttp3.Callback
import okhttp3.Response
import org.json.JSONObject
import java.net.URLDecoder

/**
 * 作者：
 * 时间：2017/6/26
 * 说明：
 */

class OkHttpResoutCallBack : Callback {
    private var httpFinish: OnHttpFinish? = null
    private var httpCode: OnHttpCode? = null
    private var mType: Int = 0
    private var direct: Boolean = false
    private var mHandle: Handler? = null
    private var mPath: String = ""
    private var mCallBack: OkHttpCallback.Callback? = null
    private var mImgCallBack: OkHttpCallback.ImgCallback? = null
    private var mDownLoadCallBack: OkHttpCallback.ProgressCallback? = null
    private var baseModel:BaseHttpModel? = null

    constructor(callback: OkHttpCallback.Callback?, handler: Handler, httpFinish: OnHttpFinish? = null, httpCode: OnHttpCode? = null,direct:Boolean = false,baseModel:BaseHttpModel? = null) {
        this.mType = 1
        this.direct = direct
        this.mCallBack = callback
        this.mHandle = handler
        this.httpFinish = httpFinish
        this.httpCode = httpCode
        this.baseModel = baseModel
        mHandle?.post { mCallBack?.onStart() }
    }

    constructor(callback: OkHttpCallback.ImgCallback, handler: Handler, httpFinish: OnHttpFinish? = null, httpCode: OnHttpCode? = null,baseModel:BaseHttpModel? = null) {
        this.mType = 2
        this.mImgCallBack = callback
        this.mHandle = handler
        this.httpFinish = httpFinish
        this.httpCode = httpCode
        this.baseModel = baseModel
        mHandle?.post { mImgCallBack?.onStart() }
    }

    constructor(path: String, callback: OkHttpCallback.ProgressCallback, handler: Handler, httpFinish: OnHttpFinish? = null, httpCode: OnHttpCode? = null,baseModel:BaseHttpModel? = null) {
        this.mType = 3
        this.mPath = path
        this.mDownLoadCallBack = callback
        this.mHandle = handler
        this.httpFinish = httpFinish
        this.baseModel = baseModel
        this.httpCode = httpCode
        mHandle?.post { mDownLoadCallBack?.onStart() }
    }

    override fun onFailure(call: Call, e: IOException) {
        baseModel?.apply {
            result = e.toString()
            print()
        }
        mHandle?.post {
            when (mType) {
                1 -> mCallBack?.onFailure(-1, e.message.toString())
                2 -> mImgCallBack?.onFailure(e)
                3 -> mDownLoadCallBack?.onFailure(e)
            }
            mCallBack?.onFinish()
            httpFinish?.finish()
        }

        call.cancel()
    }

    override fun onResponse(call: Call, response: Response) {
        if (response.isSuccessful) {
            response.body?.apply {
                when (mType) {
                    1 -> onSuccessStringMethod(string(), call)
                    2 -> {
                        val data = bytes()
                        val bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
                        onSuccessImgMethod(bitmap, call)
                    }
                    3 -> onSuccessDownLoadMethod(call, response)
                }
            }
        } else {
            baseModel?.apply {
                result = response.toString()
                print()
            }
            mHandle?.post {
//                Toast.makeText(SDActivityManager.instance.lastActivity,"请求失败！请重试",Toast.LENGTH_LONG).show()
                mCallBack?.onFailure(-1, response.message.toString())
                mCallBack?.onFinish()
                httpFinish?.finish()
            }
        }
    }

    /**
     * 处理String请求
     * @param re
     */
    private fun onSuccessStringMethod(re: String, call: Call) {
        var result = re
        if(BaseConfig.getInstance.isURLDecoder()) result = URLDecoder.decode(result,"UTF-8")
        baseModel?.apply {
            baseModel!!.result = result
            print()
        }
        mHandle?.post {
            mCallBack?.apply {
                if(direct){
                    onSuccess(result)
                }else{
                    try {
                        val obj = JSONObject(result)
                        val code = obj[BaseConfig.getInstance.getSuccessCodeName()].toString()
                        var msg = ""
                        try{
                            msg = obj[BaseConfig.getInstance.getSuccessMsgName()].toString()
                        }catch (e:Exception){ }

                        mHandle?.post {
                            httpCode?.apply {
                                baseModel?.apply {
                                    code(code.toInt(),msg,http)
                                }
                            }
                        }
                        if(code == BaseConfig.getInstance.getSuccessCode()){
                            onSuccessBase(result)
                            onSuccess(result)
                        }else{
                            onFailure(code.toInt(),msg)
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()

                        onFailure(-1,e.toString())
                    }
                }
                httpFinish?.finish()
                onFinish()
                call.cancel()
            }
        }
    }

    /**
     * 处理图片请求
     * @param bitmap
     */
    private fun onSuccessImgMethod(bitmap: Bitmap, call: Call) {
        mHandle?.post{
            mImgCallBack?.apply {
                try {
                    onSuccess(bitmap)
                } catch (e: Exception) {
                    e.printStackTrace()
                    onFailure(e)
                }
                onFinish()
                httpFinish?.finish()
            }
        }
    }

    /**
     * 处理下载请求
     * @param call
     * @param response
     */
    private fun onSuccessDownLoadMethod(call: Call, response: Response) {
        var `is`: InputStream? = null//输入流
        var fos: FileOutputStream? = null//输出流
        try {
            `is` = response.body!!.byteStream()//获取输入流
            val contentLenght = response.body!!.contentLength()
            if (`is` != null) {
                val file = File(mPath)
                fos = FileOutputStream(file)
                val buf = ByteArray(1024)
                var ch = 0
                var process = 0
                while (process!=contentLenght.toInt() && ch != -1) {
                    ch = `is`.read(buf)
                    fos.write(buf, 0, ch)
                    process += ch
                    val finalProcess = process
                    mHandle?.post {
                        mDownLoadCallBack?.onResponseProgress(
                            (finalProcess * 1.0f / contentLenght * 100).toLong(),
                            100,
                            false
                        )
                    }
                }
                mHandle?.post {
                    mDownLoadCallBack?.onSuccess(file)
                }
                baseModel?.apply {
                    this.result = file.path
                    print()
                }
            }
            fos?.flush()
            // 下载完成
            fos?.close()
        } catch (e: Exception) {
            mHandle?.post { mDownLoadCallBack?.onFailure(e) }
            baseModel?.apply {
                this.result = e.message.toString()
                print()
            }
        } finally {
            try {
                `is`?.close()
            } catch (e: IOException) {
            }

            try {
                fos?.close()
            } catch (e: IOException) {
            }

        }
        mHandle?.post {
            mDownLoadCallBack?.onFinish()
            httpFinish?.finish()
            call.cancel()
        }
    }

    interface OnHttpFinish{
        fun finish()
    }
    interface OnHttpCode{
        fun code(code:Int,msg:String,url:String)
    }
}
